package gui;


import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.FontMetrics;

import javax.swing.AbstractListModel;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JTextPane;
import javax.swing.ListCellRenderer;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.Element;

public class NumeroLinhas extends JList<Object> {

	private static final long serialVersionUID = 1L;
	
	private boolean started;
	private JTextPane textPane;
	private Element root;
	private Font font;

	public NumeroLinhas(JTextPane textPane) {
		super();
		this.textPane = textPane;
		root = textPane.getDocument().getDefaultRootElement();
		setModel(new TextComponentListModel());
		setCellRenderer(new RowHeaderRenderer());
		setSizes(textPane.getFont());
		setBackground(Color.DARK_GRAY);
		setEnabled(false);
	}

	public void setSizes(Font font) {
		FontMetrics fm = getFontMetrics(font);
		setFixedCellHeight(fm.getHeight());
		setFixedCellWidth(fm.stringWidth(" 0000"));
	}

	class TextComponentListModel extends AbstractListModel<Object> implements DocumentListener, CaretListener {

		private static final long serialVersionUID = 1L;
		
		private int currentLines;

		public TextComponentListModel() {
			textPane.getDocument().addDocumentListener(this);
			textPane.addCaretListener(this);
		}

		@Override
		public int getSize() {
			return root.getElementCount();
		}

		@Override
		public Object getElementAt(int index) {
			int lines = root.getElementCount();
			if (index < lines) {
				return "" + (index + 1);
			} else {
				return "";
			}
		}

		@Override
		public void changedUpdate(DocumentEvent e) {
			font = textPane.getFont();
			setSizes(font);
		}

		@Override
		public void insertUpdate(DocumentEvent e) {
			int lines = root.getElementCount();
			if (lines >= currentLines) {
				fireIntervalAdded(this, currentLines, lines);
				currentLines = lines;
			}
		}

		@Override
		public void removeUpdate(DocumentEvent e) {
			int lines = root.getElementCount();
			if (lines <= currentLines) {
				fireIntervalRemoved(this, currentLines, lines);
				currentLines = lines;
			}
		}

		@Override
		public void caretUpdate(CaretEvent e) {
			int offset = textPane.getCaretPosition();
			int line = root.getElementIndex(offset);
			setSelectedIndex(line);
		}
	} // end TextComponentListModel

	class RowHeaderRenderer extends JLabel implements ListCellRenderer<Object> {

		private static final long serialVersionUID = 1L;
		
		RowHeaderRenderer() {
			setOpaque(true);
			setHorizontalAlignment(CENTER);
		}
		// Returns the JLabel after setting the text of the cell

		@Override
		public Component getListCellRendererComponent(@SuppressWarnings("rawtypes") JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
			if (started) {
				setFont(textPane.getFont());
			} else {
				setFont(new Font("monospaced", 0, 12));
				started = true;
			}
			setText((value == null) ? "" : value.toString());
			setBackground(Color.DARK_GRAY);
			setForeground(Color.LIGHT_GRAY);
			if (isSelected) {
				setBackground(Color.GRAY);
			}
			return this;
		}
	}

}